package com.cardcaptorsakura.controller;

import com.cardcaptorsakura.security.ContentFilterService;
import com.cardcaptorsakura.security.JwtAuthenticationFilter;
import com.cardcaptorsakura.security.JwtUtil;
import com.cardcaptorsakura.security.PersonaSwitchCooldownService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 伦理控制系统控制器
 * 提供内容过滤、人格切换管理和权限控制的API接口
 */
@Slf4j
@RestController
@RequestMapping("/api/ethics")
@RequiredArgsConstructor
@Tag(name = "伦理控制系统", description = "内容安全过滤、人格切换冷却和权限管理相关接口")
public class EthicsController {

    private final ContentFilterService contentFilterService;
    private final PersonaSwitchCooldownService cooldownService;
    private final JwtUtil jwtUtil;

    /**
     * 过滤用户输入内容
     */
    @PostMapping("/filter/input")
    @Operation(summary = "过滤用户输入内容", description = "对用户输入的内容进行安全检查和过滤")
    public ResponseEntity<Map<String, Object>> filterUserInput(
            @RequestBody Map<String, String> request) {
        
        String content = request.get("content");
        String userId = JwtAuthenticationFilter.getCurrentUserId();
        
        if (content == null || content.trim().isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "Content cannot be empty"
            ));
        }
        
        try {
            ContentFilterService.FilterResult result = contentFilterService.filterUserInput(content, userId);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("safe", result.isSafe());
            response.put("filteredContent", result.getFilteredContent());
            response.put("riskLevel", result.getRiskLevel());
            response.put("violations", result.getViolations());
            response.put("warnings", result.getWarnings());
            response.put("metadata", result.getMetadata());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error filtering user input for user: {}", userId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Content filtering failed"
            ));
        }
    }

    /**
     * 过滤AI输出内容
     */
    @PostMapping("/filter/output")
    @Operation(summary = "过滤AI输出内容", description = "对AI生成的内容进行安全检查和过滤")
    public ResponseEntity<Map<String, Object>> filterAIOutput(
            @RequestBody Map<String, String> request) {
        
        String content = request.get("content");
        String personaId = request.get("personaId");
        
        if (content == null || content.trim().isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "Content cannot be empty"
            ));
        }
        
        if (personaId == null || personaId.trim().isEmpty()) {
            personaId = JwtAuthenticationFilter.getCurrentPersona();
        }
        
        try {
            ContentFilterService.FilterResult result = contentFilterService.filterAIOutput(content, personaId);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("safe", result.isSafe());
            response.put("filteredContent", result.getFilteredContent());
            response.put("riskLevel", result.getRiskLevel());
            response.put("violations", result.getViolations());
            response.put("warnings", result.getWarnings());
            response.put("metadata", result.getMetadata());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error filtering AI output for persona: {}", personaId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Content filtering failed"
            ));
        }
    }

    /**
     * 批量过滤内容
     */
    @PostMapping("/filter/batch")
    @Operation(summary = "批量过滤内容", description = "批量对多个内容进行安全检查和过滤")
    public ResponseEntity<Map<String, Object>> batchFilterContent(
            @RequestBody Map<String, Object> request) {
        
        @SuppressWarnings("unchecked")
        List<String> contents = (List<String>) request.get("contents");
        String userId = JwtAuthenticationFilter.getCurrentUserId();
        
        if (contents == null || contents.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "Contents cannot be empty"
            ));
        }
        
        try {
            List<ContentFilterService.FilterResult> results = 
                contentFilterService.batchFilterContent(contents, userId);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("results", results);
            response.put("totalCount", results.size());
            response.put("safeCount", results.stream().mapToInt(r -> r.isSafe() ? 1 : 0).sum());
            response.put("unsafeCount", results.stream().mapToInt(r -> r.isSafe() ? 0 : 1).sum());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error batch filtering content for user: {}", userId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Batch content filtering failed"
            ));
        }
    }

    /**
     * 检查人格切换权限
     */
    @PostMapping("/persona/check-switch")
    @Operation(summary = "检查人格切换权限", description = "检查用户是否可以进行人格切换")
    public ResponseEntity<Map<String, Object>> checkPersonaSwitch(
            @RequestBody Map<String, String> request) {
        
        String fromPersonaId = request.get("fromPersonaId");
        String toPersonaId = request.get("toPersonaId");
        String switchTypeStr = request.get("switchType");
        
        String userId = JwtAuthenticationFilter.getCurrentUserId();
        String userType = JwtAuthenticationFilter.getCurrentUserType();
        
        if (toPersonaId == null || toPersonaId.trim().isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "Target persona ID is required"
            ));
        }
        
        try {
            PersonaSwitchCooldownService.UserType userTypeEnum = 
                parseUserType(userType);
            PersonaSwitchCooldownService.SwitchType switchTypeEnum = 
                parseSwitchType(switchTypeStr);
            
            PersonaSwitchCooldownService.SwitchResult result = 
                cooldownService.canSwitchPersona(userId, fromPersonaId, toPersonaId, 
                                                userTypeEnum, switchTypeEnum);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("allowed", result.isAllowed());
            response.put("reason", result.getReason());
            response.put("remainingCooldownSeconds", result.getRemainingCooldownSeconds());
            response.put("remainingSwitchesToday", result.getRemainingSwitchesToday());
            response.put("remainingSwitchesThisHour", result.getRemainingSwitchesThisHour());
            response.put("nextAllowedTime", result.getNextAllowedTime());
            response.put("metadata", result.getMetadata());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error checking persona switch for user: {}", userId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Persona switch check failed"
            ));
        }
    }

    /**
     * 记录人格切换
     */
    @PostMapping("/persona/record-switch")
    @Operation(summary = "记录人格切换", description = "记录用户的人格切换操作")
    public ResponseEntity<Map<String, Object>> recordPersonaSwitch(
            @RequestBody Map<String, String> request) {
        
        String fromPersonaId = request.get("fromPersonaId");
        String toPersonaId = request.get("toPersonaId");
        String switchTypeStr = request.get("switchType");
        
        String userId = JwtAuthenticationFilter.getCurrentUserId();
        String userType = JwtAuthenticationFilter.getCurrentUserType();
        
        if (toPersonaId == null || toPersonaId.trim().isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "Target persona ID is required"
            ));
        }
        
        try {
            PersonaSwitchCooldownService.UserType userTypeEnum = 
                parseUserType(userType);
            PersonaSwitchCooldownService.SwitchType switchTypeEnum = 
                parseSwitchType(switchTypeStr);
            
            cooldownService.recordPersonaSwitch(userId, fromPersonaId, toPersonaId, 
                                               userTypeEnum, switchTypeEnum);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "Persona switch recorded successfully");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error recording persona switch for user: {}", userId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Persona switch recording failed"
            ));
        }
    }

    /**
     * 获取用户切换统计
     */
    @GetMapping("/persona/statistics")
    @Operation(summary = "获取用户切换统计", description = "获取用户的人格切换统计信息")
    public ResponseEntity<Map<String, Object>> getSwitchStatistics() {
        String userId = JwtAuthenticationFilter.getCurrentUserId();
        String userType = JwtAuthenticationFilter.getCurrentUserType();
        
        try {
            PersonaSwitchCooldownService.UserType userTypeEnum = 
                parseUserType(userType);
            
            Map<String, Object> statistics = 
                cooldownService.getSwitchStatistics(userId, userTypeEnum);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("statistics", statistics);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error getting switch statistics for user: {}", userId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Failed to get switch statistics"
            ));
        }
    }

    /**
     * 获取用户切换历史
     */
    @GetMapping("/persona/history")
    @Operation(summary = "获取用户切换历史", description = "获取用户的人格切换历史记录")
    public ResponseEntity<Map<String, Object>> getSwitchHistory(
            @Parameter(description = "返回记录数量限制") @RequestParam(defaultValue = "20") int limit) {
        
        String userId = JwtAuthenticationFilter.getCurrentUserId();
        
        try {
            List<Map<String, Object>> history = 
                cooldownService.getSwitchHistory(userId, limit);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("history", history);
            response.put("count", history.size());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error getting switch history for user: {}", userId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Failed to get switch history"
            ));
        }
    }

    /**
     * 获取内容过滤统计信息
     */
    @GetMapping("/filter/statistics")
    @Operation(summary = "获取内容过滤统计信息", description = "获取内容过滤系统的统计信息")
    public ResponseEntity<Map<String, Object>> getFilterStatistics() {
        try {
            Map<String, Object> statistics = contentFilterService.getFilterStatistics();
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("statistics", statistics);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error getting filter statistics", e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Failed to get filter statistics"
            ));
        }
    }

    /**
     * 管理员：清除用户冷却
     */
    @PostMapping("/admin/clear-cooldown")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "清除用户冷却", description = "管理员清除指定用户的人格切换冷却")
    public ResponseEntity<Map<String, Object>> clearUserCooldown(
            @RequestBody Map<String, String> request) {
        
        String targetUserId = request.get("userId");
        String adminUserId = JwtAuthenticationFilter.getCurrentUserId();
        
        if (targetUserId == null || targetUserId.trim().isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "User ID is required"
            ));
        }
        
        try {
            cooldownService.clearUserCooldown(targetUserId);
            
            log.info("Admin {} cleared cooldown for user: {}", adminUserId, targetUserId);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "User cooldown cleared successfully");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error clearing cooldown for user: {} by admin: {}", targetUserId, adminUserId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Failed to clear user cooldown"
            ));
        }
    }

    /**
     * 管理员：重置用户切换计数
     */
    @PostMapping("/admin/reset-switch-count")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "重置用户切换计数", description = "管理员重置指定用户的人格切换计数")
    public ResponseEntity<Map<String, Object>> resetUserSwitchCount(
            @RequestBody Map<String, String> request) {
        
        String targetUserId = request.get("userId");
        String adminUserId = JwtAuthenticationFilter.getCurrentUserId();
        
        if (targetUserId == null || targetUserId.trim().isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "User ID is required"
            ));
        }
        
        try {
            cooldownService.resetUserSwitchCount(targetUserId);
            
            log.info("Admin {} reset switch count for user: {}", adminUserId, targetUserId);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "User switch count reset successfully");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error resetting switch count for user: {} by admin: {}", targetUserId, adminUserId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Failed to reset user switch count"
            ));
        }
    }

    /**
     * 管理员：更新敏感词库
     */
    @PostMapping("/admin/update-sensitive-words")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "更新敏感词库", description = "管理员更新内容过滤的敏感词库")
    public ResponseEntity<Map<String, Object>> updateSensitiveWords(
            @RequestBody Map<String, Object> request) {
        
        @SuppressWarnings("unchecked")
        Set<String> words = new HashSet<>((List<String>) request.get("words"));
        String operation = (String) request.get("operation"); // add, remove, replace
        String adminUserId = JwtAuthenticationFilter.getCurrentUserId();
        
        if (words == null || words.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "Words list cannot be empty"
            ));
        }
        
        try {
            switch (operation != null ? operation.toLowerCase() : "add") {
                case "add":
                    contentFilterService.addSensitiveWords(words);
                    break;
                case "remove":
                    contentFilterService.removeSensitiveWords(words);
                    break;
                case "replace":
                    contentFilterService.updateSensitiveWords(words);
                    break;
                default:
                    return ResponseEntity.badRequest().body(Map.of(
                        "success", false,
                        "message", "Invalid operation. Use 'add', 'remove', or 'replace'"
                    ));
            }
            
            log.info("Admin {} updated sensitive words: operation={}, count={}", 
                    adminUserId, operation, words.size());
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "Sensitive words updated successfully");
            response.put("operation", operation);
            response.put("wordsCount", words.size());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("Error updating sensitive words by admin: {}", adminUserId, e);
            return ResponseEntity.internalServerError().body(Map.of(
                "success", false,
                "message", "Failed to update sensitive words"
            ));
        }
    }

    /**
     * 解析用户类型
     */
    private PersonaSwitchCooldownService.UserType parseUserType(String userType) {
        if (userType == null) {
            return PersonaSwitchCooldownService.UserType.NORMAL;
        }
        
        try {
            return PersonaSwitchCooldownService.UserType.valueOf(userType.toUpperCase());
        } catch (IllegalArgumentException e) {
            return PersonaSwitchCooldownService.UserType.NORMAL;
        }
    }

    /**
     * 解析切换类型
     */
    private PersonaSwitchCooldownService.SwitchType parseSwitchType(String switchType) {
        if (switchType == null) {
            return PersonaSwitchCooldownService.SwitchType.NORMAL;
        }
        
        try {
            return PersonaSwitchCooldownService.SwitchType.valueOf(switchType.toUpperCase());
        } catch (IllegalArgumentException e) {
            return PersonaSwitchCooldownService.SwitchType.NORMAL;
        }
    }
}